using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Collections.ObjectModel;
using System.Collections.Specialized;

namespace qPrintComponent
{

    [TypeConverter(typeof(ExpandableObjectConverter)), Browsable(true), RefreshProperties(RefreshProperties.None)]
    public sealed class qAttributes
    {
        private qSafePrinterInfo _printerinfo; 
        private int _attributes;

        public qAttributes(qSafePrinterInfo printerinfo, int attributes)
        {
            _printerinfo = printerinfo;
            _attributes = attributes;
        }

        public override string ToString()
        {
            return System.Enum.Format(typeof(PrinterAttributes), _attributes, "g");
        }

        [Description("Indicates the printer is the default printer in the system.")]
        public bool IsDefault
        {
            get
            {
                string s;
                if (_printerinfo.Level == 2)
                    s = _printerinfo.GetStringField(1);
                else
                    s = _printerinfo.GetStringField(0);
                return s.Equals(qStatic.GetDefaultPrinter());
            }
            set
            {
                string s;
                if (_printerinfo.Level == 2)
                    s = _printerinfo.GetStringField(1);
                else
                    s = _printerinfo.GetStringField(0); 
                if (value)
                    qStatic.SetDefaultprinter(s);
                else
                {
                    foreach (string printername in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
                    {
                        if (printername != s)
                        {
                            qStatic.SetDefaultprinter(printername);
                            System.Windows.Forms.MessageBox.Show(printername + " is now the Default Printer");
                            break;
                        }
                    }
                }
            }
        }


        [Description("Job is sent directly to printer (it is not spooled). ")]
        public bool IsDirectPrinting
        {
            get { return GetPrinterAttributes(PrinterAttributes.Direct); }
            set { SetPrinterAttributes(PrinterAttributes.Direct); }
        }
        [Description("If set and printer is set for print-while-spooling, any jobs that have completed spooling are scheduled to print before jobs that have not completed spooling.")]
        public bool IsDoCompleteFirst
        {
            get { return GetPrinterAttributes(PrinterAttributes.ScheduleCompletedJobsFirst); }
            set { SetPrinterAttributes(PrinterAttributes.ScheduleCompletedJobsFirst); }
        }
        [Description("Windows 95/98/Me: Indicates whether bidirectional communications are enabled for the printer.")]
        public bool IsBiDirectional
        {
            get { return GetPrinterAttributes(PrinterAttributes.EnableBidi); }
        }
        [Description("Indicates whether mismatched documents to be held in the queue.")]
        public bool IsHoldingMismatched
        {
            get { return GetPrinterAttributes(PrinterAttributes.EnableDevQuery); }
            set { SetPrinterAttributes(PrinterAttributes.EnableDevQuery); }
        }
        [Description("If set, jobs are kept after they have printed. If unset, jobs are deleted.")]
        public bool IsKeepingPrintedJobs
        {
            get { return GetPrinterAttributes(PrinterAttributes.KeepPrintedJobs); }
            set { SetPrinterAttributes(PrinterAttributes.KeepPrintedJobs); }
        }
        [Description("If set, the printer spools and starts printing after the last page is spooled. If not set and PRINTER_ATTRIBUTE_DIRECT is not set, the printer spools and prints while spooling.")]
        public bool IsQueued
        {
            get { return GetPrinterAttributes(PrinterAttributes.Queued); }
            set { SetPrinterAttributes(PrinterAttributes.Queued); }
        }
        [Description("Printer is shared. ")]
        public bool IsShared
        {
            get { return GetPrinterAttributes(PrinterAttributes.Shared); }
        }
        [Description("Windows 95/98/Me: Indicates whether the printer is currently connected. If the printer is not currently connected, print jobs will continue to spool.")]
        public bool IsWorkOffline
        {
            get { return GetPrinterAttributes(PrinterAttributes.WorkOffline); }
            set { SetPrinterAttributes(PrinterAttributes.WorkOffline); }
        }
        [Description("Windows 2000/XP: Indicates whether the printer is published in the directory service.")]
        public bool IsPublished
        {
            get { return GetPrinterAttributes(PrinterAttributes.Published); }
        }
        [Description("Printer is a network printer connection.")]
        public bool IsNetwork
        {
            get { return GetPrinterAttributes(PrinterAttributes.NetWork); }
        }
        [Description("Printer is a local printer.")]
        public bool IsLocal
        {
            get { return GetPrinterAttributes(PrinterAttributes.Local); }
        }
        [Description("Indicates that only RAW data type print jobs can be spooled. ")]
        public bool IsRawOnly
        {
            get { return GetPrinterAttributes(PrinterAttributes.RawOnly); }
        }
        [Description("Printer is a Fax")]
        public bool IsFax
        {
            get { return GetPrinterAttributes(PrinterAttributes.Fax); }
        }
        [Description("Printer is hidden")]
        public bool IsHidden
        {
            get { return GetPrinterAttributes(PrinterAttributes.Hidden); }
        }
        private bool GetPrinterAttributes(PrinterAttributes fwt)
        {
            int i = (int)fwt;
            return (Attributes & i) == i;
        }

        private void SetPrinterAttributes(PrinterAttributes fwt)
        {
            //if (_printerinfo.Level == 4)
            //{
            //    System.Windows.Forms.MessageBox.Show("Update not Possible");
            //    return;
            //}
            int i = (int)fwt;
            int at = Attributes;
            if ((i & at) == i)
                at ^= i;
            else
                at |= i;
            if (_printerinfo.Level == 2)
                _printerinfo.SetIntField(13,at);
            else
                _printerinfo.SetIntField(2,at);

        }
        internal int Attributes
        {
            get { return _attributes; }
        }


        [Flags]
        private enum PrinterAttributes : int
        {
            None = 0,
            Queued = 1,
            Direct = 2,
            Default = 4,
            Shared = 8,
            NetWork = 0x10,
            Hidden = 0x20,
            Local = 0x40,
            EnableDevQuery = 0x80,
            KeepPrintedJobs = 0x100,
            ScheduleCompletedJobsFirst = 0x200,
            WorkOffline = 0x400,
            EnableBidi = 0x800,
            RawOnly = 0x1000,
            Published = 0x2000,
            Fax = 0x4000
        }

    }
}
